package com.castle.fortress.admin.cms.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.castle.fortress.admin.cms.dto.*;
import com.castle.fortress.admin.cms.entity.CmsChannelEntity;
import com.castle.fortress.admin.cms.entity.CmsModelEntity;
import com.castle.fortress.admin.cms.enums.ChannelCategoryEnum;
import com.castle.fortress.admin.cms.fragment.*;
import com.castle.fortress.admin.cms.service.*;
import com.castle.fortress.admin.core.constants.GlobalConstants;
import com.castle.fortress.admin.core.handler.CastleBtlErrorHandler;
import com.castle.fortress.common.enums.ViewFormTypeEnum;
import com.castle.fortress.common.enums.YesNoEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.FileResourceLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * cms通用配置表 控制器
 *
 * @author castle
 * @since 2022-02-18
 */
@Api(tags="cms路由控制器")
@Controller
public class CmsRouterController {
	@Autowired
	private CmsConfigService cmsConfigService;
	@Autowired
	private CmsTemplateService cmsTemplateService;
	@Autowired
	private CmsChannelService cmsChannelService;
	@Autowired
	private CmsSubjectService cmsSubjectService;
	@Autowired
	private CmsCustTagService cmsCustTagService;
	@Autowired
	private CmsSysTagService cmsSysTagService;
	@Autowired
	private CmsArticleService cmsArticleService;
	@Autowired
	private CmsModelService cmsModelService;
	@Autowired
	private CmsModelDataService cmsModelDataService;
	@Autowired
	private CmsColConfigService cmsColConfigService;
	@Value("${castle.cms.templatePath}")
	private String templatePath;

	/**
	 * 首页
	 * @return
	 */
	@ApiOperation("cms首页")
	@RequestMapping(path= {"index.*","index",""})
	public void pageIndex(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		try {
			resp.setContentType("text/html;charset=utf-8");
			resp.setCharacterEncoding("utf-8");
			Template t = initT("index.html");
			resp.getOutputStream().write(t.render().getBytes("utf-8"));
		} catch (Exception e) {
			e.printStackTrace();
			resp.sendRedirect("/404");
		}
	}

	/**
	 * 列表页
	 * @return
	 */
	@ApiOperation("列表页")
	@RequestMapping({"page/{code}"})
	public void pageList(HttpServletRequest req, HttpServletResponse resp, @PathVariable("code") String code) throws IOException {
		try {
			resp.setContentType("text/html;charset=utf-8");
			resp.setCharacterEncoding("utf-8");
			if(StrUtil.isEmpty(code)){
				resp.sendRedirect("/404");
				return;
			}
			String[] p= code.split("-");
			String queryCode =code;
			Integer current=1;
			//后续页
			if(p.length == 2){
				queryCode=p[0];
				try {
					current = Integer.parseInt(p[1]);
				} catch (NumberFormatException e) {
					resp.sendRedirect("/404");
					return;
				}
			}else if(p.length>2){
				resp.sendRedirect("/404");
				return;
			}
			// 00 列表类文章 01 专题文章分页 02 标签文章分页
			String codeFlag = null;
			String templateName = null;
			CmsChannelDto queryDto=new CmsChannelDto();
			queryDto.setCode(queryCode);
			List<CmsChannelDto> channelDtos =cmsChannelService.listCmsChannel(queryDto);
			CmsChannelDto channelDto=null;
			CmsSubjectDto subjectDto=null;
			CmsCustTagDto custTagDto = null;
			if(channelDtos!=null && !channelDtos.isEmpty()){
				codeFlag = "00";
				channelDto = channelDtos.get(0);
			}else{
				//专题
				CmsSubjectDto querySubjectDto=new CmsSubjectDto();
				querySubjectDto.setCode(queryCode);
				List<CmsSubjectDto> subjectDtos =cmsSubjectService.listCmsSubject(querySubjectDto);
				if(subjectDtos!=null && !subjectDtos.isEmpty()){
					codeFlag = "01";
					subjectDto=subjectDtos.get(0);
				}else{
					//用户自定义标签
					CmsCustTagDto queryTagDto=new CmsCustTagDto();
					queryTagDto.setTitle(queryCode);
					List<CmsCustTagDto> tagDtos =cmsCustTagService.listCmsCustTag(queryTagDto);
					if(tagDtos!=null && !tagDtos.isEmpty()){
						codeFlag = "02";
						custTagDto=tagDtos.get(0);
					}else{
						resp.sendRedirect("/404");
						return;
					}
				}
			}
			//顶级渠道编码
			String topCode=null;
			if("00".equals(codeFlag)){
				//封面
				if(ChannelCategoryEnum.COVER.getCode().equals(channelDto.getCategory())){
					if(StrUtil.isEmpty(channelDto.getCovertp())){
						resp.sendRedirect("/404");
						return;
					}
					templateName= channelDto.getCovertp();
				//列表
				}else if(ChannelCategoryEnum.LIST.getCode().equals(channelDto.getCategory())){
					templateName= StrUtil.isNotEmpty(channelDto.getListtp())?channelDto.getListtp():"list.html";
				//外链
				}else if(ChannelCategoryEnum.WEBURL.getCode().equals(channelDto.getCategory())){
					resp.sendRedirect(StrUtil.isNotEmpty(channelDto.getWeburl())?channelDto.getWeburl():"/404");
					return;
				}else{
					resp.sendRedirect("/404");
					return;
				}
				//获取顶级code
				 if(StrUtil.isNotEmpty(channelDto.getParents())){
					CmsChannelEntity parent= cmsChannelService.getById(channelDto.getParents().split(",")[0]);
					 topCode=parent.getCode();
				 }else{
					 topCode = channelDto.getCode();
				 }

			}else if("01".equals(codeFlag)){//取专题模板
				templateName= StrUtil.isNotEmpty(subjectDto.getListtp())?subjectDto.getListtp():"special.html";
			}else if("02".equals(codeFlag)){//取标签模板
				templateName= StrUtil.isNotEmpty(custTagDto.getListtp())?custTagDto.getListtp():"tag.html";
			}else{
				resp.sendRedirect("/404");
				return;
			}
			Template t = initT(templateName);
			t.binding("current",current);
			t.binding("code",queryCode);
			if(StrUtil.isNotEmpty(topCode)){
				t.binding("topcode",topCode);
			}
			t.binding("urlpre","/page/"+queryCode+"/");
			t.binding("pageurl","/page/"+queryCode+"-");
			t.binding("currenturl","/page/"+code);
			if("00".equals(codeFlag)){
				t.binding("channelinfo",channelDto);
				//查询当前路径
				List<CmsChannelDto> positions = cmsChannelService.cmsTagPositionByDto(channelDto);
				t.binding("positions",positions);
			}else if("01".equals(codeFlag)){
				t.binding("specialinfo",subjectDto);
			}else if("02".equals(codeFlag)){
				t.binding("taginfo",custTagDto);
			}
			resp.getOutputStream().write(t.render().getBytes("utf-8"));
		} catch (Exception e) {
			e.printStackTrace();
			resp.sendRedirect("/404");
		}
	}

	/**
	 * 文章页
	 * @return
	 */
	@ApiOperation("文章页")
	@RequestMapping({"page/{code}/{articleid}"})
	public void pageArticle(HttpServletRequest req, HttpServletResponse resp, @PathVariable("code") String code, @PathVariable("articleid") String articleid) throws IOException {
		try {
			resp.setContentType("text/html;charset=utf-8");
			resp.setCharacterEncoding("utf-8");
			if(StrUtil.isEmpty(articleid) || StrUtil.isEmpty(code)){
				resp.sendRedirect("/404");
				return;
			}
			// 00 列表类文章 01 专题文章分页 02 标签文章分页
			String codeFlag = "00";
			List<CmsArticleDto> articles = cmsArticleService.listByChannel(code);
			if(articles==null || articles.isEmpty()){
				codeFlag = "01";
				articles = cmsArticleService.listBySubject(code);
				if(articles==null || articles.isEmpty()){
					codeFlag = "02";
					articles = cmsArticleService.listByTag(code);
				}
			}
			if(articles==null || articles.isEmpty()){
				resp.sendRedirect("/404");
				return;
			}
			Long id = Long.parseLong(articleid);
			CmsArticleDto article=null,pre=null,next=null;
			for(int i=0;i<articles.size();i++){
				if(articles.get(i).getId().equals(id)){
					article = articles.get(i);
					if(i>0){
						pre = articles.get(i-1);
					}
					if(i<articles.size()-1){
						next = articles.get(i+1);
					}
				}
			}
			//文章基本信息
			if(article==null){
				resp.sendRedirect("/404");
				return;
			}
			article.setTagInfos(cmsCustTagService.listByArticle(id));
			article.setAttrInfos(cmsSysTagService.listCmsSysTagByAtri(id));
			//栏目基本信息
			CmsChannelEntity cmsChannelEntity = cmsChannelService.getById(article.getChannelId());
			if(cmsChannelEntity == null){
				resp.sendRedirect("/404");
				return;
			}
			//查询当前路径
			CmsChannelDto channelDto = new CmsChannelDto();
			channelDto.setId(cmsChannelEntity.getId());
			List<CmsChannelDto> positions = cmsChannelService.cmsTagPositionByDto(channelDto);

			//获取顶级code
			String topCode=null;
			if(StrUtil.isNotEmpty(cmsChannelEntity.getParents())){
				CmsChannelEntity parent= cmsChannelService.getById(cmsChannelEntity.getParents().split(",")[0]);
				topCode=parent.getCode();
			}else{
				topCode = cmsChannelEntity.getCode();
			}
			CmsModelEntity modelEntity = cmsModelService.getById(cmsChannelEntity.getModel());
			Map<String,Object> art = new HashMap<>();
			if(YesNoEnum.YES.getCode().equals(modelEntity.getIsExtend())){
				art = cmsModelDataService.queryById(modelEntity.getCode(),article.getId().toString());
				List<CmsColConfigDto> list = cmsColConfigService.listByChannel(article.getChannelId());
				if(art == null){
					art = new HashMap<>();
					//特殊字段处理
					for(CmsColConfigDto d:list){
						art.put(d.getPropName(),"");
					}
					art.put("id",id);
				}
				//特殊字段处理
				for(CmsColConfigDto d:list){
					//多图片
					if(ViewFormTypeEnum.IMAGE_UPLOAD.getCode().equals(d.getFormType()) && d.getLimitSize()>1 && art.get(d.getPropName())!=null){
						art.put(d.getPropName(),art.get(d.getPropName()).toString().split(","));
					}
					//文件
					if(ViewFormTypeEnum.FILE_UPLOAD.getCode().equals(d.getFormType()) && art.get(d.getPropName())!=null){
						JSONArray files= new JSONArray(art.get(d.getPropName()));
						List<Map<String,String>> f= new ArrayList<>();
						for(int i=0;i<files.size();i++){
							JSONObject o= files.getJSONObject(i);
							Map<String,String> m = new HashMap<>();
							m.put("name",o.getStr("name"));
							m.put("url",o.getStr("url"));
							f.add(m);
						}
						art.put(d.getPropName(),f);
					}
					//日期
					if(ViewFormTypeEnum.DATE.getCode().equals(d.getFormType()) && art.get(d.getPropName())!=null){
						art.put(d.getPropName(), art.get(d.getPropName()).toString());
					}
					//日期时间
					if(ViewFormTypeEnum.DATE_TIME.getCode().equals(d.getFormType()) && art.get(d.getPropName())!=null){
						art.put(d.getPropName(), DateUtil.format((Date)art.get(d.getPropName()),"yyyy-MM-dd HH:mm:ss"));
					}
				}
			}
			art.putAll(BeanUtil.beanToMap(article));
			String templateName = cmsChannelEntity.getArticletp();

			Template t = initT(templateName);
			t.binding("code",code);
			t.binding("topcode",topCode);
			t.binding("urlpre","/page/"+code+"/");
			t.binding("listurl","/page/"+code);
			t.binding("currenturl","/page/"+code+"/"+articleid);
			t.binding("arti",art);
			t.binding("hasprearti",pre!=null);
			t.binding("hasnextarti",next!=null);
			t.binding("prearti",pre);
			t.binding("nextarti",next);
			t.binding("positions",positions);
			resp.getOutputStream().write(t.render().getBytes("utf-8"));
		} catch (Exception e) {
			e.printStackTrace();
			resp.sendRedirect("/404");
		}
	}

	/**
	 * 文章搜索页
	 * @return
	 */
	@ApiOperation("文章搜索页")
	@RequestMapping({"page/search"})
	public void pageSearch(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		try {
			resp.setContentType("text/html;charset=utf-8");
			resp.setCharacterEncoding("utf-8");
			String templateName = "search.html";
			String name="";
			Integer pageindex=GlobalConstants.DEFAULT_PAGE_INDEX,pagesize= GlobalConstants.DEFAULT_PAGE_SIZE;
			//搜索的关键字 此处可对查询信息处理
			if(StrUtil.isNotEmpty(req.getParameter("name"))){
				name = req.getParameter("name");
			}
			//当前页
			if(StrUtil.isNotEmpty(req.getParameter("pageindex"))){
				try {
					Integer i = Integer.parseInt(req.getParameter("pageindex"));
					if(i>0){
						pageindex = i;
					}
				} catch (NumberFormatException e) {
				}
			}
			//每页显示数量
			if(StrUtil.isNotEmpty(req.getParameter("pagesize"))){
				try {
					Integer s = Integer.parseInt(req.getParameter("pagesize"));
					if(s>0){
						pagesize = s;
					}
				} catch (NumberFormatException e) {
				}
			}
			Template t = initT(templateName);
			t.binding("current",pageindex);
			t.binding("pagesize",pagesize);
			t.binding("searchvalue",name);
			t.binding("urlpre","/page/search?name="+name+"&pagesize="+pagesize+"&pageindex=");
			t.binding("pageurl","/page/search?name="+name+"&pagesize="+pagesize+"&pageindex=");
			t.binding("currenturl","/page/search?name="+name+"&pagesize="+pagesize+"&pageindex="+pageindex);
			resp.getOutputStream().write(t.render().getBytes("utf-8"));
		} catch (Exception e) {
			e.printStackTrace();
			resp.sendRedirect("/404");
		}
	}


	private Template initT(String templateName){
		CmsTemplateDto dto = cmsTemplateService.getActiveTemp();
		FileResourceLoader frl = new FileResourceLoader(templatePath+dto.getTitle()+"/","utf-8");
		Configuration cfg = null;
		try {
			cfg = Configuration.defaultConfiguration();
		} catch (IOException e) {
			e.printStackTrace();
		}
		cfg.setStatementStart("@");
		cfg.setStatementEnd(null);
		GroupTemplate gt = new GroupTemplate(frl,cfg);
		//注册 栏目/导航 标签
		gt.registerTag("cms_channels", CmsChannelTag.class);
		//注册 友链组 标签
		gt.registerTag("cms_links_groups", CmsLinkGroupTag.class);
		//注册 友链 标签
		gt.registerTag("cms_links", CmsLinkTag.class);
		//注册 轮播图 标签
		gt.registerTag("cms_banners", CmsBannerTag.class);
		//列表类栏目文章列表
		gt.registerTag("cms_articlelist", CmsArticleListTag.class);
		//注册 分页 标签
		gt.registerTag("cms_page", CmsPageTag.class);
		//注册 专题 标签
		gt.registerTag("cms_specials", CmsSpecialTag.class);
		//注册 专题类文章列表
		gt.registerTag("cms_speciallist", CmsSpecialArticleListTag.class);
		//注册 自定义标签 标签
		gt.registerTag("cms_tags", CmsTagTag.class);
		//注册 自定义标签类文章列表
		gt.registerTag("cms_taglist", CmsTagArticleListTag.class);
		//注册 搜索文章列表
		gt.registerTag("cms_searchlist", CmsSearchArticleListTag.class);
		//指定文章
		gt.registerTag("cms_article", CmsArticleTag.class);
		gt.setErrorHandler(new CastleBtlErrorHandler());
		Template t = gt.getTemplate(templateName);
		//绑定通用配置参数
		List<CmsConfigDto> configList = cmsConfigService.listCmsConfig(null);
		Map<String,Object> configMap= new HashMap<>();
		configList.forEach(item->{
			if(StrUtil.isNotEmpty(item.getTagName())){
				configMap.put(item.getTagName(),item.getTagValues());
			}
		});
		t.binding(configMap);
		return t;
	}




}
